package com.aispeech.rcprvd;

import android.app.Application;
import android.util.Log;

import com.aispeech.rcprvd.jni.RcNativeProcessJni;
import com.aispeech.rcprvd.provider.base.IDataProvider;
import com.aispeech.rcprvd.provider.JinJuGattDataProvider;
import com.aispeech.rcprvd.provider.NanoBleNodeDataProvider;
import com.aispeech.rcprvd.provider.NanoHidIntDataProvider;
import com.aispeech.rcprvd.utils.RcPrvdConst;
import com.aispeech.rcprvd.utils.RemoteDeviceUtils;

import androidx.annotation.NonNull;

import static com.aispeech.rcprvd.utils.RcPrvdConst.ErrorCode;

public class RemoteRecord {
    private final String TAG = "RemoteProvider";

    private IDataProvider mDataProvider;
    private RcPrvdListener mListener;
    private RecordState mRecordState;

    public enum RecordState {
        UNINIT, IDLE, RUNNING
    }

    static {
        try {
            System.loadLibrary("rcnative");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private RemoteRecord() {
    }

    private static class SingletonHolder {

        private static final RemoteRecord INSTANCE = new RemoteRecord();
    }

    /**
     * 获取当前连接的遥控器设备对象
     *
     * @return 遥控器对象
     */
    public RemoteDevice getDevice() {
        return null;
    }

    /**
     * 获取lib库版本号
     *
     * @return 版本号
     */
    public String getLibVersion() {
        return BuildConfig.LIB_VERSION;
    }

    /**
     * 获取遥控器录音提供者实例
     *
     * @return 遥控器音频数据提供者
     */
    public static RemoteRecord getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 初始化数据提供者
     *
     * @param devSource  数据源
     * @param appContext 应用上下文
     * @param listener   监听回调,用于获取音频数据和按键事件
     * @return 根据不同的返回值判断是否初始化成功
     * 可以在#RcPrvdConst.ErrorCode中查询
     */
    public int init(int devSource, @NonNull Application appContext, @NonNull RcPrvdListener listener) {
        Log.d(TAG, "initProvider: ");
        RemoteDevice remoteDevice = RemoteDeviceUtils.checkCurrentRemoteDevice(devSource, appContext);
        if (null == remoteDevice) {
            mRecordState = RecordState.UNINIT;
            return ErrorCode.NO_DEVICE_FOUND;
        }

        switch (devSource) {
            case RcPrvdConst.RCDevSource.NANO_HID:
                mDataProvider = new NanoHidIntDataProvider(appContext, remoteDevice);
                break;
            case RcPrvdConst.RCDevSource.NANO_BLE_NODE:
                mDataProvider = new NanoBleNodeDataProvider();
                break;
            case RcPrvdConst.RCDevSource.JINJU_BLE_GATT:
                mDataProvider = new JinJuGattDataProvider(appContext, listener);
                break;
            default:
                Log.w(TAG, "init: current transfer moder not support :" + " source = " + devSource
                        + " transfer = " + remoteDevice.getDataTransferMode());
                mRecordState = RecordState.UNINIT;
                return ErrorCode.TRANSFER_TYPE_NOT_SUPPORT;
        }

        mListener = listener;
        int nativeRet = RcNativeProcessJni.native_process_init(mNativeListener);
        if (nativeRet != ErrorCode.NO_ERROR) {
            mRecordState = RecordState.UNINIT;
            return ErrorCode.NATIVE_ERR;
        }

        mRecordState = RecordState.IDLE;
        return ErrorCode.NO_ERROR;
    }

    /**
     * 销毁数据提供者
     */
    public void release() {
        Log.d(TAG, "release: ");
        if (null != mDataProvider) {
            mDataProvider.stop();
            RcNativeProcessJni.native_process_destroy();
            mRecordState = RecordState.UNINIT;
        }
    }

    /**
     * 开始读取音频数据和监听按键事件
     */
    public int start() {
        int ret;

        if (mRecordState == RecordState.IDLE) {
            ret = mDataProvider.start();
            if (ret == ErrorCode.NO_ERROR) {
                mRecordState = RecordState.RUNNING;
            }
        } else {
            Log.w(TAG, "start: record state : " + mRecordState);
            ret = ErrorCode.RECORD_STATE_ERR;
        }
        return ret;

    }

    /**
     * 停止读取音频数据和按键监听
     */
    public int stop() {
        int ret;

        if (mRecordState == RecordState.RUNNING) {
            ret = mDataProvider.stop();
            if (ret == ErrorCode.NO_ERROR) {
                mRecordState = RecordState.IDLE;
            }
        } else {
            Log.w(TAG, "stop: record state : " + mRecordState);
            ret = ErrorCode.RECORD_STATE_ERR;
        }
        return ret;
    }

    private RcNativeProcessJni.RcNativeListener mNativeListener = new RcNativeProcessJni.RcNativeListener() {
        @Override
        public void onKeyEvent(int keyCode, int state) {
            Log.d(TAG, "onKeyEvent() called with: keyCode = [" + keyCode + "], state = [" + state + "]");
            if (null != mListener) {
                mListener.onKeyEvent(keyCode, state);
            }
        }

        @Override
        public void onBuffer(byte[] audioData) {
            if (null != mListener) {
                mListener.onBuffer(audioData);
            }
        }
    };

}
